#!/usr/bin/env ruby

class Canonizer
  RIGHT_SINGLE_QUOTE = "\x92"
  SOFT_HYPHEN = "\xAD"
  PUNCTUATIONS = "-#{SOFT_HYPHEN}'#{RIGHT_SINGLE_QUOTE}"
  
  TRANSLATES = {
    "\xC0\xC1\xC2\xC4\xE0\xE1\xE2\xE4" => 'a', 
    "\xC8\xC9\xCA\xCB\xE8\xE9\xEA\xEB" => 'e', 
    "\xCC\xCD\xCE\xCF\xEC\xED\xEE\xEF" => 'i', 
    "\xD2\xD3\xD4\xD6\xF2\xF3\xF4\xF6" => 'o', 
    "\xD9\xDA\xDB\xDC\xF9\xFA\xFB\xFC" => 'u', 
    "\xC7\xE7" => 'c', 
    "\xD1\xF1" => 'n', 
  }
  
  SUBS = {
    /[\xC6\xE6]/ => 'ae', 
    /[\x8C\x9C]/ => 'oe', # CP-1252 only?, not in Latin1?
    /\xDF/ => 'ss', 
  }
  
  def self.norm_text(text)
    raise TypeError, 'arg must be String' unless text.is_a?(String)
    
    s = text.delete(PUNCTUATIONS).downcase
    TRANSLATES.each { |k, v| s.tr!(k, v) }
    SUBS.each { |k, v| s.gsub!(k, v) }
    return s.tr_s('^a-z', ' ').strip
  end
  
  def self.norm_fname(fname)
    raise TypeError, 'arg must be String' unless fname.is_a?(String)
    
    s = fname.downcase
    TRANSLATES.each { |k, v| s.tr!(k, v) }
    SUBS.each { |k, v| s.gsub!(k, v) }
    return s.delete('^a-z')
  end
end

########################################

def __foreigns
  return {
    "CH\xc2TEAU" => 'chateau', 
    "\xc9T\xc9"  => 'ete', 
    "\xceLE"     => 'ile', 
    "H\xd4PITAL" => 'hopital', 
    "GEF\xdcLTE" => 'gefulte', 
    "I\xc7I"     => 'ici', 
    "MA\xd1ANA"  => 'manana', 
    "\xc6SOP"    => 'aesop', 
    "\x8cDIPUS"  => 'oedipus', 
    "MU\xdf"     => 'muss', 
  }
end

def _test_norm_text
  # preconditions
  n = 123
  begin
    Canonizer.norm_text(n)
    raise Exception, 'should never get here'
  rescue TypeError
    Canonizer.norm_text(n.to_s)
  end
  
  # postconditions
  good_chars = ('a'..'z').join + ' '
  assert Canonizer.norm_text(String.all_chars.join).chars_in?(good_chars)
  assert_equal '', Canonizer.norm_text('')
  assert_equal '', Canonizer.norm_text(" \r\n \n\n \t ")
  assert_equal '', Canonizer.norm_text("-'\xAD\x92")
  assert_equal 'foo bar', Canonizer.norm_text('FOO   BAR')
  s = "  1) Desire: Howard's   \nwell-being  to-day!! \n"
  assert_equal 'desire howards wellbeing today', Canonizer.norm_text(s)
  __foreigns.each { |k, v| assert_equal v, Canonizer.norm_text(k) }
end

def _test_norm_fname
  # preconditions
  n = 123
  begin
    Canonizer.norm_fname(n)
    raise Exception, 'should never get here'
  rescue TypeError
    Canonizer.norm_fname(n.to_s)
  end
  
  # postconditions
  good_chars = ('a'..'z').join
  assert Canonizer.norm_fname(String.all_chars.join).chars_in?(good_chars)
  assert_equal '', Canonizer.norm_fname('')
  assert_equal '', Canonizer.norm_fname(" \r\n \n\n \t ")
  assert_equal '', Canonizer.norm_fname('123')
  assert_equal 'foobar', Canonizer.norm_fname('FOO   BAR')
  s = "1927-09-12 NYT p3 Cry-baby Bandit's Mother Faints"
  assert_equal 'nytpcrybabybanditsmotherfaints', Canonizer.norm_fname(s)
  __foreigns.each { |k, v| assert_equal v, Canonizer.norm_fname(k) }
end

########################################

if $0 == __FILE__
  require 'assert'
  require File.join(File.dirname(__FILE__), '..', 'monkey', 'range')
  require File.join(File.dirname(__FILE__), '..', 'monkey', 'string')
  
  _test_norm_text
  _test_norm_fname
  puts 'all asserts pass :-)'
end
